﻿using Stee.CAP8.MessageBus.Sagas.Core.Ioc;
using System;
using System.ComponentModel;
using Microsoft.Extensions.DependencyInjection;
using System.Runtime.CompilerServices;
using System.Reflection;

namespace Stee.CAP8.MessageBus.Sagas.Core.Sagas.SagaData
{
    public abstract class BaseSagaData : INotifyPropertyChanged
    {
        protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        private object _childInstance;
        protected BaseSagaData(string sagaId)
        {
            SagaId = sagaId ?? throw new ArgumentNullException(nameof(sagaId));
            LoadData();
        }

        private void BaseSagaData_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            lock (this)
            {
                var provider = SagaContainer.serviceProvider;
                var storage = provider.GetService<ISagaStorage>();

                var propertynfo = GetType().GetProperty(e.PropertyName, BindingFlags.Public | BindingFlags.Instance);
                bool.TryParse(propertynfo.GetValue(sender).ToString(), out var proValue);

                storage.Insert(SagaId,
                    new SagaDataProperty() { PropertyName = e.PropertyName, PropertyValue = proValue }
                    );
                Console.WriteLine($"存储SagaId={SagaId}-,{e.PropertyName}={proValue}");

            }
        }

        public bool LoadData()
        {
            lock (this)
            {
                PropertyChanged = null;
                var provider = SagaContainer.serviceProvider;
                var storage = provider.GetService<ISagaStorage>();
                var properties = storage.Find(SagaId);
                Console.WriteLine("========================================================");
                Console.Write($"从数据库加载SagaId={SagaId}");
                properties?.ForEach(property =>
                {

                    var propertynfo = GetType().GetProperty(property.PropertyName, BindingFlags.Public | BindingFlags.Instance);
                    propertynfo.SetValue(this, property.PropertyValue);
                    Console.Write($"{property.PropertyName}={property.PropertyValue},");

                });
                Console.WriteLine();
                Console.WriteLine("========================================================");
                PropertyChanged = BaseSagaData_PropertyChanged;
                return true;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public string SagaId { get; set; }
        public abstract bool IsDone();

    }
}
